package org.Yiran.timetale_re.item.runeblueprint.base;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.network.chat.TextColor;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.Yiran.timetale_re.client.gui.runeblueprint.LifeRuneCarvingScreen;
import org.Yiran.timetale_re.client.gui.runeblueprint.StormRuneCarvingScreen;
import org.Yiran.timetale_re.client.gui.runeblueprint.ThunderRuneCarvingScreen;
import org.Yiran.timetale_re.client.gui.base.RuneCarvingScreen;
import org.Yiran.timetale_re.item.ItemsRegister;
import org.Yiran.timetale_re.util.item.TooltipUtils;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nullable;
import java.util.List;

/**
 * 符文图纸物品类
 * <p>
 * 该类表示游戏中的符文图纸物品，通过NBT数据区分不同类型的符文图纸。
 * 符文图纸可以被玩家使用以打开雕刻界面，用于制作各种类型的符文。
 * 支持多种符文类型，包括风暴、雷暴、生命等类型，并具有等级系统。
 * </p>
 */
public class RuneBlueprintItem extends Item {

    // ==============================
    // 常量定义
    // ==============================

    /**
     * NBT标签中存储符文类型的关键字
     */
    public static final String RUNE_TYPE = "RuneType";
    
    /**
     * 风暴符文类型标识符
     */
    public static final String STORM = "storm";
    
    /**
     * 雷暴符文类型标识符
     */
    public static final String THUNDER = "thunder";
    
    /**
     * 生命符文类型标识符
     */
    public static final String LIFE = "life";
    
    /**
     * NBT标签中存储符文等级的关键字
     */
    public static final String RUNE_LEVEL = "RuneLevel";

    // ==============================
    // 构造方法
    // ==============================

    /**
     * 构造函数
     * <p>
     * 创建一个新的符文图纸物品实例。
     * </p>
     *
     * @param properties 物品属性配置对象
     */
    public RuneBlueprintItem(Properties properties) {
        super(properties);
    }

    // ==============================
    // 符文等级相关方法
    // ==============================

    /**
     * 设置符文图纸等级
     * <p>
     * 将指定的等级值写入符文图纸物品的NBT数据中。
     * </p>
     *
     * @param stack 符文图纸物品栈
     * @param level 要设置的等级值
     */
    public static void setRuneLevel(ItemStack stack, int level) {
        CompoundTag tag = stack.getOrCreateTag();
        tag.putInt(RUNE_LEVEL, level);
    }

    /**
     * 获取符文图纸等级
     * <p>
     * 从符文图纸物品的NBT数据中读取等级值。
     * 如果未设置等级，则返回默认值1。
     * </p>
     *
     * @param stack 符文图纸物品栈
     * @return 符文等级，如果未设置则返回默认值1
     */
    public static int getRuneLevel(ItemStack stack) {
        CompoundTag tag = stack.getTag();
        if (tag != null && tag.contains(RUNE_LEVEL)) {
            return tag.getInt(RUNE_LEVEL);
        }
        return 1; // 默认等级为1
    }

    // ==============================
    // 创建符文图纸方法
    // ==============================

    /**
     * 创建指定等级的风暴符文图纸
     * <p>
     * 创建一个新的风暴符文图纸物品栈，并设置其类型和等级。
     * </p>
     *
     * @param level 符文等级
     * @return 对应的符文图纸物品栈
     */
    public static ItemStack createStormRuneBlueprint(int level) {
        ItemStack stack = new ItemStack(getRuneBlueprintItem());
        setRuneType(stack, STORM);
        setRuneLevel(stack, level);
        return stack;
    }

    /**
     * 创建指定等级的雷暴符文图纸
     * <p>
     * 创建一个新的雷暴符文图纸物品栈，并设置其类型和等级。
     * </p>
     *
     * @param level 符文等级
     * @return 对应的符文图纸物品栈
     */
    public static ItemStack createThunderRuneBlueprint(int level) {
        ItemStack stack = new ItemStack(getRuneBlueprintItem());
        setRuneType(stack, THUNDER);
        setRuneLevel(stack, level);
        return stack;
    }

    /**
     * 创建指定等级的生命符文图纸
     * <p>
     * 创建一个新的生命符文图纸物品栈，并设置其类型和等级。
     * </p>
     *
     * @param level 符文等级
     * @return 对应的符文图纸物品栈
     */
    public static ItemStack createLifeRuneBlueprint(int level) {
        ItemStack stack = new ItemStack(getRuneBlueprintItem());
        setRuneType(stack, LIFE);
        setRuneLevel(stack, level);
        return stack;
    }

    /**
     * 创建风暴符文图纸（默认等级）
     * <p>
     * 创建一个新的风暴符文图纸物品栈，并设置其类型。
     * 等级使用默认值1。
     * </p>
     *
     * @return 对应的符文图纸物品栈
     */
    public static ItemStack createStormRuneBlueprint() {
        ItemStack stack = new ItemStack(getRuneBlueprintItem());
        setRuneType(stack, STORM);
        return stack;
    }

    /**
     * 创建雷暴符文图纸（默认等级）
     * <p>
     * 创建一个新的雷暴符文图纸物品栈，并设置其类型。
     * 等级使用默认值1。
     * </p>
     *
     * @return 对应的符文图纸物品栈
     */
    public static ItemStack createThunderRuneBlueprint() {
        ItemStack stack = new ItemStack(getRuneBlueprintItem());
        setRuneType(stack, THUNDER);
        return stack;
    }

    /**
     * 创建生命符文图纸（默认等级）
     * <p>
     * 创建一个新的生命符文图纸物品栈，并设置其类型。
     * 等级使用默认值1。
     * </p>
     *
     * @return 对应的符文图纸物品栈
     */
    public static ItemStack createLifeRuneBlueprint() {
        ItemStack stack = new ItemStack(getRuneBlueprintItem());
        setRuneType(stack, LIFE);
        return stack;
    }

    // ==============================
    // 符文类型相关方法
    // ==============================

    /**
     * 获取符文图纸物品实例
     * <p>
     * 从物品注册表中获取符文图纸物品的实例。
     * </p>
     *
     * @return 符文图纸物品
     */
    public static Item getRuneBlueprintItem() {
        return ItemsRegister.RUNE_BLUEPRINT.get();
    }

    /**
     * 设置符文图纸类型
     * <p>
     * 将指定的符文类型写入符文图纸物品的NBT数据中。
     * </p>
     *
     * @param stack 符文图纸物品栈
     * @param type  要设置的符文类型
     */
    public static void setRuneType(ItemStack stack, String type) {
        CompoundTag tag = stack.getOrCreateTag();
        tag.putString(RUNE_TYPE, type);
    }

    /**
     * 获取符文图纸类型
     * <p>
     * 从符文图纸物品的NBT数据中读取符文类型。
     * 如果未设置类型，则返回null。
     * </p>
     *
     * @param stack 符文图纸物品栈
     * @return 符文类型，如果未设置则返回null
     */
    public static String getRuneType(ItemStack stack) {
        CompoundTag tag = stack.getTag();
        if (tag != null && tag.contains(RUNE_TYPE)) {
            return tag.getString(RUNE_TYPE);
        }
        return null; // 默认为空白符文图纸
    }

    /**
     * 检查是否为风暴符文图纸
     * <p>
     * 判断给定的物品栈是否为风暴符文图纸。
     * </p>
     *
     * @param stack 符文图纸物品栈
     * @return 如果是风暴符文图纸返回true，否则返回false
     */
    public static boolean isStormRuneBlueprint(ItemStack stack) {
        return STORM.equals(getRuneType(stack));
    }

    /**
     * 检查是否为雷暴符文图纸
     * <p>
     * 判断给定的物品栈是否为雷暴符文图纸。
     * </p>
     *
     * @param stack 符文图纸物品栈
     * @return 如果是雷暴符文图纸返回true，否则返回false
     */
    public static boolean isThunderRuneBlueprint(ItemStack stack) {
        return THUNDER.equals(getRuneType(stack));
    }

    /**
     * 检查是否为生命符文图纸
     * <p>
     * 判断给定的物品栈是否为生命符文图纸。
     * </p>
     *
     * @param stack 符文图纸物品栈
     * @return 如果是生命符文图纸返回true，否则返回false
     */
    public static boolean isLifeRuneBlueprint(ItemStack stack) {
        return LIFE.equals(getRuneType(stack));
    }

    // ==============================
    // 物品交互方法
    // ==============================

    /**
     * 使用物品时的处理方法
     * <p>
     * 当玩家使用符文图纸时调用此方法，根据符文类型打开不同的雕刻界面。
     * 仅在客户端执行界面打开操作。
     * </p>
     *
     * @param level  世界对象
     * @param player 玩家对象
     * @param hand   使用的手
     * @return 交互结果
     */
    @Override
    public @NotNull InteractionResultHolder<ItemStack> use(Level level, Player player, @NotNull InteractionHand hand) {
        ItemStack stack = player.getItemInHand(hand);

        // 只在客户端打开GUI
        if (level.isClientSide) {
            // 播放打开GUI的翻书声
            player.playSound(SoundEvents.BOOK_PAGE_TURN);

            String runeType = getRuneType(stack);

            // 根据符文类型打开不同的GUI
            if (runeType != null) {
                switch (runeType) {
                    case STORM:
                        Minecraft.getInstance().setScreen(new StormRuneCarvingScreen(stack));
                        break;
                    case THUNDER: // 添加雷暴符文图纸的支持
                        Minecraft.getInstance().setScreen(new ThunderRuneCarvingScreen(stack));
                        break;
                    case LIFE: // 添加生命符文图纸的支持
                        Minecraft.getInstance().setScreen(new LifeRuneCarvingScreen(stack));
                        break;
                    default:
                        Minecraft.getInstance().setScreen(new RuneCarvingScreen(stack));
                        break;
                }
            }
        }

        return InteractionResultHolder.success(stack);
    }

    // ==============================
    // 客户端显示方法
    // ==============================

    /**
     * 添加物品悬停文本提示
     * <p>
     * 在物品悬停时显示相关信息，包括基础描述、等级和详细信息。
     * 详细信息仅在按住Shift键时显示。
     * </p>
     *
     * @param stack   物品栈
     * @param level   世界对象
     * @param tooltip 提示文本列表
     * @param flag    提示标志
     */
    @Override
    @OnlyIn(Dist.CLIENT)
    public void appendHoverText(@NotNull ItemStack stack, @Nullable Level level, @NotNull List<Component> tooltip, @NotNull TooltipFlag flag) {
        super.appendHoverText(stack, level, tooltip, flag);

        String runeType = getRuneType(stack);
        int runeLevel = getRuneLevel(stack);

        // 添加基础描述（不包含等级信息）
        TooltipUtils.addRuneBlueprintBaseDescription(tooltip, runeType);

        // 添加符文图纸等级
        TooltipUtils.addArcaneLevel(tooltip, runeLevel);

        // 隔一行
        TooltipUtils.addSeparatorLine(tooltip);

        // 检查是否按下了Shift键
        boolean isShiftPressed = Screen.hasShiftDown();

        if (isShiftPressed) {
            // 显示详细信息
            TooltipUtils.addRuneBlueprintDetailedInfo(tooltip, runeType);
        } else {
            // 提示按Shift查看详细信息
            TooltipUtils.addShiftPrompt(tooltip);
        }
    }

    /**
     * 获取物品显示名称
     * <p>
     * 根据符文类型返回对应的本地化名称。
     * </p>
     *
     * @param stack 物品栈
     * @return 物品名称组件
     */
    @Override
    public @NotNull Component getName(@NotNull ItemStack stack) {
        String runeType = getRuneType(stack);
        return Component.translatable("item.timetale_re." + runeType + "_rune_blueprint");
    }
}